import re
from langchain_core.output_parsers import BaseOutputParser


from langchain.prompts import (
    SystemMessagePromptTemplate,
    ChatPromptTemplate,
    HumanMessagePromptTemplate,
)

from llm.llm import llm
import uuid
import json


class vue_output_parser(BaseOutputParser[str]):
    def parse(self, text: str) -> str:
        # print("htmlOutputParser:", text)
        pattern = r"```vue(.*?)```"
        matches = re.findall(pattern, text, re.DOTALL)
        if matches:
            return matches[0].strip()
        else:
            return "未找到vue代码"

    @property
    def _type(self) -> str:
        return ""


class htmlOutputParser(BaseOutputParser[str]):
    def parse(self, text: str) -> str:
        # print("htmlOutputParser:", text)
        pattern = r"```html(.*?)```"
        matches = re.findall(pattern, text, re.DOTALL)
        if matches:
            return matches[0].strip()
        else:
            return "未找到HTML代码"

    @property
    def _type(self) -> str:
        return ""


class jsonOutputParser(BaseOutputParser[str]):
    def parse(self, text: str) -> str:
        # print("htmlOutputParser:", text)
        pattern = r"```json(.*?)```"
        matches = re.findall(pattern, text, re.DOTALL)
        if matches:
            return matches[0].strip()
        else:
            return "未找到HTML代码"

    @property
    def _type(self) -> str:
        return ""


def extract_data(desc, require=""):
    sys_tmp = """\
        角色设定：参数分析助手
        职责：首先分析输入数据，然后根据输出数据格式提取对应参数，最后根据输出数据格式返回结果。

        {{require}}

        输出数据：
        ```json
        [{{"label": "数据名称", "value": "数据数值"}}]
        ```
    """

    human_tmp = """\
        输入内容：
        {desc}
    """

    sys_msg = SystemMessagePromptTemplate.from_template(sys_tmp)
    human_msg = HumanMessagePromptTemplate.from_template(human_tmp)
    chat_msg = ChatPromptTemplate.from_messages([sys_msg, human_msg])

    data = ""
    try:
        chain = (chat_msg | llm | jsonOutputParser()).with_retry()
        data = chain.invoke(
            {"desc": desc, "require": require},
        )
        print("data", data)
    except Exception as e:
        print(e)
        return "数据分析失败，请重试"

    return data


def build_vue_chart(summary, filename=""):
    sys_tmpl = """
    根据内容创建一个美观的Vue 3 Setup语法组件：

    布局结构：
    使用全局<app-container>组件作为最外层包裹，不需要import
    
    可选组件：
    <app-chatjs :options="chatOptions" /> chat.jsVue组件（chatOptions就是chat.js的配置））

    要求：
    使用现代UI设计原则
    一致的配色方案
    清晰的视觉层次
    """

    human_tmpl = "输入内容：\n{summary}"

    system_prompt = SystemMessagePromptTemplate.from_template(sys_tmpl)
    human_prompt = HumanMessagePromptTemplate.from_template(human_tmpl)
    chat_prompt = ChatPromptTemplate.from_messages([system_prompt, human_prompt])

    # print("chat_prompt", chat_prompt.content)

    chain = (chat_prompt | llm | vue_output_parser()).with_retry()

    res = chain.invoke({"summary": summary})

    if filename == "":
        filename = str(uuid.uuid4()) + ".vue"

    # 保存
    with open("./web/public/remote-component/" + filename, "w", encoding="utf-8") as f:
        f.write(res)

    return filename


def build_vue(summary, filename=""):
    sys_tmpl = """
    根据内容创建一个美观的Vue 3 Setup语法组件：

    基础结构
    使用 <script setup> 语法
    使用全局 `<app-container>` 组件作为最外层包裹（无需 import）

    图表集成
    系统已经集成 `<app-chartjs :options="chartOptions" />` chat.js全局组件， chartOptions就是chat.js的配置
   

    要求：
    完全符合 Vue 3 最佳实践
    使用现代UI设计原则
    一致的配色方案
    清晰的视觉层次
    """

    human_tmpl = "输入内容：\n{summary}"

    system_prompt = SystemMessagePromptTemplate.from_template(sys_tmpl)
    human_prompt = HumanMessagePromptTemplate.from_template(human_tmpl)
    chat_prompt = ChatPromptTemplate.from_messages([system_prompt, human_prompt])

    # print("chat_prompt", chat_prompt.content)

    chain = (chat_prompt | llm | vue_output_parser()).with_retry()

    res = chain.invoke({"summary": summary})

    if filename == "":
        filename = str(uuid.uuid4()) + ".vue"

    # 保存
    with open("./web/public/remote-component/" + filename, "w", encoding="utf-8") as f:
        f.write(res)

    return filename


# 读取文件
def read_file(filename):
    with open(filename, "r", encoding="utf-8") as f:
        return f.read()


# 读取JSON
def read_json(filename):
    with open(filename, "r", encoding="utf-8") as f:
        return json.load(f)
